package model.formats;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import tools.Translator;
import view.ResultFormatter;
import view.formatters.BPSResultFormatter;
import model.DebateFormat;
import model.SpeakerRole;

import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.multibindings.MapBinder;
import com.google.inject.multibindings.Multibinder;

public class BPSModule extends AbstractModule {

	/**
	 * Used for the first government speaker.
	 */
	public static final SpeakerRole FIRST_GOV = new SpeakerRole("BPS_FIRST_GOV");
	
	/**
	 * Used for the first opposition speaker.
	 */
	public static final SpeakerRole FIRST_OP = new SpeakerRole("BPS_FIRST_OP");
	
	/**
	 * Used for the second government speaker.
	 */
	public static final SpeakerRole SECOND_GOV = new SpeakerRole("BPS_SECOND_GOV");

	/**
	 * Used for the second opposition speaker.
	 */
	public static final SpeakerRole SECOND_OP = new SpeakerRole("BPS_SECOND_OP");

	/**
	 * Used for the third government speaker.
	 */
	public static final SpeakerRole THIRD_GOV = new SpeakerRole("BPS_THIRD_GOV");
	
	/**
	 * Used for the third opposition speaker.
	 */
	public static final SpeakerRole THIRD_OP = new SpeakerRole("BPS_THIRD_OP");

	/**
	 * Used for the third government speaker.
	 */
	public static final SpeakerRole FOURTH_GOV = new SpeakerRole("BPS_THIRD_GOV");
	
	/**
	 * Used for the third opposition speaker.
	 */
	public static final SpeakerRole FOURTH_OP = new SpeakerRole("BPS_THIRD_OP");

	@Override
	protected void configure() {
		
		List<SpeakerRole> govRoles = Arrays.asList(new SpeakerRole[] {FIRST_GOV, SECOND_GOV, THIRD_GOV, FOURTH_GOV});
		List<SpeakerRole> opRoles = Arrays.asList(new SpeakerRole[] {FIRST_OP, SECOND_OP, THIRD_OP, FOURTH_OP});
		List<SpeakerRole> roleOrder = Arrays.asList(new SpeakerRole[] {FIRST_GOV, SECOND_GOV, THIRD_GOV, FIRST_OP, SECOND_OP, THIRD_OP, FOURTH_GOV, FOURTH_OP});
		
		DebateFormat bpsFormat = new DebateFormat("BPS_DESC", 8, 8, govRoles, opRoles, Collections.<SpeakerRole>emptyList(), roleOrder);
		
		Multibinder.newSetBinder(binder(), DebateFormat.class).addBinding().toInstance(bpsFormat);
		
		MapBinder.newMapBinder(binder(), DebateFormat.class, ResultFormatter.class).addBinding(bpsFormat).toProvider(BPSResultFormatterProvider.class);
		
		Multibinder<SpeakerRole> roleBinder = Multibinder.newSetBinder(binder(), SpeakerRole.class);
		roleBinder.addBinding().toInstance(FIRST_GOV);
		roleBinder.addBinding().toInstance(FIRST_OP);
		roleBinder.addBinding().toInstance(SECOND_GOV);
		roleBinder.addBinding().toInstance(SECOND_OP);
		roleBinder.addBinding().toInstance(THIRD_GOV);
		roleBinder.addBinding().toInstance(THIRD_OP);
		roleBinder.addBinding().toInstance(FOURTH_GOV);
		roleBinder.addBinding().toInstance(FOURTH_OP);
	}

		static class BPSResultFormatterProvider implements Provider<ResultFormatter> {

			private Translator tr;
			
			@Inject 
			public BPSResultFormatterProvider (Translator tr) {
				this.tr = tr;
			}
			
			@Override
			public ResultFormatter get() {
				return new BPSResultFormatter(tr, FIRST_GOV, SECOND_GOV, THIRD_GOV, FOURTH_GOV, FIRST_OP, SECOND_OP, THIRD_OP, FOURTH_OP);
			}
			
		}
}
